package com.zh.ssmshirofreemarker.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.zh.ssmshirofreemarker.entity.JsTree;
import com.zh.ssmshirofreemarker.entity.Permission;
import com.zh.ssmshirofreemarker.mapper.PermissionMapper;
import com.zh.ssmshirofreemarker.service.IPermissionService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zh.ssmshirofreemarker.service.RedisService;
import com.zh.ssmshirofreemarker.websocket.Msg;
import com.zh.ssmshirofreemarker.websocket.WebSocketTest;
import org.apache.shiro.SecurityUtils;
import com.zh.ssmshirofreemarker.shiro.MyShiroRealm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.websocket.EncodeException;
import java.io.IOException;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ZH
 * @since 2018-07-24
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {

    @Autowired
    PermissionMapper permissionMapper;

    @Autowired
    RedisService redisService;
    @Override
    public List<Map<String,Object>> getAllMenu() {
        if(redisService.exists("menuList")){
            return (List<Map<String, Object>>) redisService.get("menuList");
        }
        List<Permission> menus = permissionMapper.getAllMenu();
        Permission rootMenu = null;
        try{
            rootMenu = selectOne(new EntityWrapper<Permission>().eq("url","/")
                                                                .eq("permission","system:view"));
        } catch (Exception e){
            e.printStackTrace();
        }
        List<Map<String,Object>> list = new ArrayList<>();
        for(Permission permission : menus){
            if(permission.getParentId() != null && permission.getParentId() == rootMenu.getPermissionId()){   //把顶级菜单排除在外
                Map<String,Object> temp  = new HashMap<>();
                temp.put("permissionId",permission.getPermissionId());
                temp.put("permission",permission.getPermission());
                temp.put("permissionName",permission.getPermissionName());
                temp.put("url",permission.getUrl());
                temp.put("icon",permission.getIcon());
                temp.put("parentId",permission.getParentId());
                List<Map<String,Object>> childList = getChildList(permission.getPermissionId(),menus);
                temp.put("childList",childList);
                list.add(temp);
            }
        }
        redisService.set("menuList",list);
        return list;
    }

    /**
     * 把数据库中的数据转换成 jstree需要的格式
     * @return
     */
    @Override
    public List<JsTree> getAllMenuForJson() {
        if(redisService.exists("JsTreeList")){
            return (List<JsTree>) redisService.get("JsTreeList");
        }
        List<JsTree> jsTrees = new ArrayList<>();
        List<Permission> permissions = permissionMapper.getAllMenuForJsTree();
        String parentIdStr = null;
        for(Permission p : permissions){
            if(p.getParentId() != null){
                parentIdStr = p.getParentId().toString();
            }
            jsTrees.add(new JsTree(p.getPermissionId().toString(),
                    p.getUrl().equals("/") && p.getPermission().equals("system:view")
                    ? "#": parentIdStr,p.getPermissionName()));
        }
        redisService.set("JsTreeList",jsTrees);
        return jsTrees;
    }

    @Override
    public Page<Permission> getPermissionPage(Page<Permission> page, Permission permission) {
        return page.setRecords(permissionMapper.selectPermissionList(page,permission));
    }

    @Override
    public int addPermission(Permission permission) {
        permission.setDeleteFlag(0);
        //permission.setIdChain();
        return permissionMapper.insert(permission);
    }

    @Override
    public boolean doAdd(Permission permission) {
        permission.setIdChain(getIdChain(permission));
        int count = 0;
        try{
            count = permissionMapper.insert(permission);
        } catch (Exception e){
            e.printStackTrace();
        }
        if(count > 0){
            clearCache();  //添加成功，清空缓存
          return true;
        }
        return false;
    }

    public void clearCache(){
        redisService.remove("JsTreeList");
        redisService.remove("menuList");
        MyShiroRealm.clearCachedAuthorization();
        MyShiroRealm.clearCachedAuthentication();
    }

    public String getIdChain(Permission permission){
        Permission parentPermission = null;
        try {
            parentPermission = permissionMapper.selectById(permission.getParentId());
        } catch (Exception e){
             e.printStackTrace();
        }
        if(permission != null){
           return parentPermission.getIdChain() + "," + permission.getPermissionId();
        }
        return null;
    }

    @Override
    public boolean doUpdate(Permission permission) {
        if(permission.getParentId() == permission.getPermissionId()){   //这里不允许自己作为自己的父菜单，如果当前菜单id与父菜单id相同则直接返回false
           return false;
        }
        permission.setIdChain(getIdChain(permission));       //设置id链
        int count = 0;
        try{
            count = permissionMapper.updateById(permission);
        } catch (Exception e){
            e.printStackTrace();
        }
        if(count > 0){
            clearCache(); //修改成功清空缓存
            return true;
        }
        return false;
    }


    @Override
    public boolean deletePermisisonByIds(Collection collection) throws IOException, EncodeException {
        int count = permissionMapper.deleteBatchIds(collection);
        if(count > 0){
           //删除之后向客户端推送数据
            Msg msg = new Msg(0,"权限删除成功",new Date());
            WebSocketTest.sendMessage(JSONObject.toJSONString(msg),SecurityUtils.getSubject().getPrincipal().toString());
            clearCache(); //删除成功清空缓存
           return true;
        }
        return false;
    }

    private List<Map<String,Object>> getChildList(Long parentId,List<Permission> menus) {
        List<Map<String,Object>> tempList = new ArrayList<>();

        for(Permission permission : menus){
            if(permission.getParentId() == parentId){
                Map<String,Object> temp = new HashMap<>();
                temp.put("permissionId",permission.getPermissionId());
                temp.put("permissionName",permission.getPermissionName());
                temp.put("permission",permission.getPermission());
                temp.put("url",permission.getUrl());
                temp.put("icon",permission.getIcon());
                temp.put("parentId",permission.getParentId());
                List<Map<String,Object>> childList = getChildList(permission.getPermissionId(),menus);
                temp.put("childList",childList);
                tempList.add(temp);
            }
        }
        return tempList;
    }


}
